﻿using RazorEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Compilation;
using System.Web.Mvc;
using System.Web.WebPages;

namespace TaoPortal.Common
{
    /// <summary>
    /// 皮肤视图
    /// </summary>
    public class SkinRazorView : IView
    {
        public string ViewPath { get; private set; }
        public SkinRazorView(string viewPath)
        {
            this.ViewPath = viewPath;
        }
        public void Render(ViewContext viewContext, TextWriter writer)
        {
            Type viewType = BuildManager.GetCompiledType(this.ViewPath);
            object instance = Activator.CreateInstance(viewType);
            WebViewPage page = instance as WebViewPage;
            page.VirtualPath = this.ViewPath;
            page.ViewContext = viewContext;
            page.ViewData = viewContext.ViewData;
            page.InitHelpers();
            WebPageContext pageContext = new WebPageContext(viewContext.HttpContext, null, null);
            //WebPageRenderingBase startPage = StartPage.GetStartPage(page, "_ViewStart", new string[] { "cshtml" });
            page.ExecutePageHierarchy(pageContext, writer);
        }
    }
    /// <summary>
    /// 将Action指定到Index，重写Result根据当前皮肤渲染页面
    /// </summary>
    public class SkinActionInvoker : ControllerActionInvoker
    {
        public override bool InvokeAction(ControllerContext controllerContext, string actionName)
        {
            actionName = "Index";
            return base.InvokeAction(controllerContext, actionName);
        }
        protected override void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
        {
            if (actionResult.GetType() == typeof(System.Web.Mvc.HttpUnauthorizedResult))
            {
                if (((System.Web.Mvc.HttpUnauthorizedResult)actionResult).StatusCode == 401)
                {
                    base.InvokeActionResult(controllerContext, actionResult);
                    return;
                }
            }
            string skinName = "Skin";
            var _skinName = controllerContext.HttpContext.Session["SkinName"];
            if (_skinName != null)
                skinName = _skinName.ToString();
            string controller = controllerContext.RouteData.Values["controller"].ToString();
            string action = controllerContext.RouteData.Values["action"].ToString();

            string viewPath = "~/Views/" + skinName + "/" + controller + "/" + action + ".cshtml";
            string dllPath = "~/Models/TaoPortal." + skinName + ".Models.dll";
            string localDLLPath = controllerContext.HttpContext.Server.MapPath(dllPath);
            string mappingTypeName = "TaoPortal." + skinName + ".Models.ModelMappings";

            //试图
            SkinRazorView view = new SkinRazorView(viewPath);
            //通过反射加载Model程序集，并获取当前页面Model
            byte[] assemblyInfo = File.ReadAllBytes(localDLLPath);
            Assembly ass = Assembly.Load(assemblyInfo);
            //System.Reflection.Assembly ass = System.Reflection.Assembly.LoadFrom(localDLLPath);
            Type mappingType = ass.GetType(mappingTypeName);
            dynamic mappingModel = Activator.CreateInstance(mappingType) as dynamic;
            dynamic model = mappingModel.GetModel(controller.ToLower(), action.ToLower(), controllerContext.HttpContext.ApplicationInstance);
            ViewDataDictionary viewData = new ViewDataDictionary(model);
            TempDataDictionary tempData = new TempDataDictionary();
            ViewContext viewContext = new ViewContext(controllerContext, view, viewData, tempData, controllerContext.HttpContext.Response.Output);
            view.Render(viewContext, viewContext.Writer);
        }
    }
    /// <summary>
    /// 默认所有网站前台请求都调用HomeController
    /// </summary>
    public class SkinControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
        {
            if (!requestContext.RouteData.DataTokens.Keys.Contains("area") 
                && !controllerName.Equals("Account", StringComparison.CurrentCultureIgnoreCase) 
                && !controllerName.Equals("File", StringComparison.CurrentCultureIgnoreCase)
                && !controllerName.Equals("DeownloadFile", StringComparison.CurrentCultureIgnoreCase) 
                && !controllerName.Equals("FileUpload", StringComparison.CurrentCultureIgnoreCase)
                && !controllerName.Equals("WebApi", StringComparison.CurrentCultureIgnoreCase))
            {
                controllerName = "Home";
            }
            return base.CreateController(requestContext, controllerName);
        }
    }
    /// <summary>
    /// 网站前端皮肤基类
    /// </summary>
    public class SkinController : Controller
    {
        protected override IActionInvoker CreateActionInvoker()
        {
            return new SkinActionInvoker();
        }
    }
}
